﻿namespace Nomo.CoreModule
{
    /// <summary>
    /// 为需要使用单一实例模式的类提供基类。
    /// </summary>
    /// <typeparam name="T">需要使用单一实例模式的类的类型。</typeparam>
    public abstract class Singleton<T>
    {
        private static readonly System.Lazy<T> Lazy = new System.Lazy<T>(
            () =>
            {
                var type = typeof(T);
                if (!type.IsSealed)
                {
                    throw new System.NotSupportedException("类必须密封。");
                }
                var constructors = type.GetConstructors(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
                if (constructors.Length == 0)
                {
                    throw new ConstructorNotFoundException(type);
                }
                var constructor = constructors[0];
                if (!constructor.IsPrivate && !constructor.IsFamily || constructor.GetParameters().Length != 0)
                {
                    throw new System.InvalidOperationException("类必须有且仅有一个构造函数，该构造函数的访问权限必须是私有的或者受保护的，并且不能有参数。");
                }
                return (T) constructor.Invoke(null);
            }
        );

        /// <summary>
        /// 需要使用单一实例模式的类的单一实例。
        /// </summary>
        public static T Instance => Lazy.Value;
    }
}
